package com.sprouting.metadata.core.service.queryImpl;

import com.sprouting.metadata.core.model.SimpleDataSource;
import com.sprouting.metadata.core.utils.StringTool;
import com.sprouting.metadata.core.interfaces.MetadataQueryInterfaces;
import com.sprouting.metadata.core.model.MetadataConfig;
import com.sprouting.metadata.core.utils.JdbcTool;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;

/**
 * Oracle获取表信息的实现
 *
 * @author ：LX（长沙麓谷）
 * @date 创建时间： 2022/4/20 9:40
 */
public class OracleInspector implements MetadataQueryInterfaces {


    /**
     * 获取表名和注释映射
     * @param simpleDataSource 数据源配置
     * @param metadataConfig 配置信息
     */
    @Override
    public Map<String, String> getTable(SimpleDataSource simpleDataSource, MetadataConfig metadataConfig) {
        Map<String, String> answer = new HashMap<String, String>();
        try {
            // all_tab_comments 查询用户全部的表
            StringBuilder sqlBuilder = new StringBuilder("select table_name tname,comments from all_tab_comments where comments is not null ");
            if (StringTool.isNotEmpty(metadataConfig.getSchemaPattern())) {
                sqlBuilder.append(" and owner like :1 ");
            }
            sqlBuilder.append("order by tname ");

            Connection connection = simpleDataSource.getConnection();
            // 预编译
            PreparedStatement preparedStatement = connection.prepareStatement(sqlBuilder.toString());
            if (StringTool.isNotEmpty(metadataConfig.getSchemaPattern())) {
                preparedStatement.setString(1, metadataConfig.getSchemaPattern());
            }
            ResultSet rs = preparedStatement.executeQuery();
            while (rs.next()) {
                // 表名
                String key = rs.getString(StringTool.convertLetterByCase("TNAME", simpleDataSource));
                // 说明
                String value = rs.getString(StringTool.convertLetterByCase("COMMENTS", simpleDataSource));
                answer.put(key, value);
            }
            JdbcTool.closeResultSet(rs);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return answer;
    }

    /**
     * 获取 表名 -> 列名-注释映射
     * @param simpleDataSource 数据源配置
     * @param metadataConfig 配置信息
     */
    @Override
    public Map<String, Map<String, String>> getColumn(SimpleDataSource simpleDataSource, MetadataConfig metadataConfig) {
        Map<String, Map<String, String>> answer = new HashMap<String, Map<String, String>>();
        try {
            StringBuilder sqlBuilder = new StringBuilder("select table_name tname,column_name cname,comments from all_col_comments ");
            sqlBuilder.append("where comments is not null ");
            if (StringTool.isNotEmpty(metadataConfig.getSchemaPattern())) {
                sqlBuilder.append(" and owner like :1 ");
            }
            sqlBuilder.append("order by table_name,column_name ");

            Connection connection = simpleDataSource.getConnection();
            // 预编译
            PreparedStatement preparedStatement = connection.prepareStatement(sqlBuilder.toString());

            if (StringTool.isNotEmpty(metadataConfig.getSchemaPattern())) {
                preparedStatement.setString(1, metadataConfig.getSchemaPattern());
            }

            // 执行查询
            ResultSet rs = preparedStatement.executeQuery();
            while (rs.next()) {
                String tname = rs.getString(StringTool.convertLetterByCase("TNAME", simpleDataSource));
                if (!answer.containsKey(tname)) {
                    answer.put(tname, new HashMap<String, String>());
                }
                // 字段名
                String key = rs.getString(StringTool.convertLetterByCase("CNAME", simpleDataSource));
                // 字段说明
                String value = rs.getString(StringTool.convertLetterByCase("COMMENTS", simpleDataSource));
                answer.get(tname).put(key, value);
            }
            JdbcTool.closeResultSet(rs);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return answer;
    }

}
